//PLC 内置CGI默认写入跟读取数据交换都是16#进行
//常用X、Y、M等都属于位1、0与通断
Vue.filter("bit", function (value) {
  if (value === "0") return 0;
  if (value === "1") return 1;

  return "----";
});

//将16进制字符串返回值'10a2'(16位)切成两个Byte '10'跟 'a2'
function str2array(str) {
  let arr = [];
  for (let i = 0; i < str.length; i += 2) {
    let subStr = str.substr(i, 2);
    arr.push(subStr);
  }
  return arr;
}
//American Standard Code for Information Interchange
//16进制数41（十进制65）对应大写字母A占，一个字符占8位
//比如D10 16# 为4241，对应内容为16#BA,三菱软件显示字符为AB
Vue.filter("ascii", function (value) {
  if (!value) return "----";
  let strArr = str2array(value).map((val) =>
    String.fromCharCode(parseInt(val, 16))
  );
  return strArr.join("");
});
//常用16位2进制表示的整数，最高位表示符号，0为正，1为负数
Vue.filter("int16", function (value) {
  if (!value) return "----";

  var b = new ArrayBuffer(2); //2*8 16位
  var a = new Uint8ClampedArray(b);
  // 将'01b0'这种拆分成'01' 'b0'高低换位后放进ArrayBuffer去再取对应格式出来
  str2array(value)
    .reverse()
    .map((val, index) => (a[index] = parseInt(val, 16)));

  return new Int16Array(b)[0];
});
//常用16位2进制表示的整数，最高位为1表示2的15次方
Vue.filter("uint16", function (value) {
  if (!value) return "----";

  var b = new ArrayBuffer(2); //2*8 16位
  var a = new Uint8ClampedArray(b);
  str2array(value)
    .reverse()
    .map((val, index) => (a[index] = parseInt(val, 16)));

  return new Uint16Array(b)[0];
});
//常用32位2进制表示的整数，最高位表示符号，0为正，1为负数
Vue.filter("int32", function (value) {
  if (!value) return "----";

  var b = new ArrayBuffer(4); //4*8 32位
  var a = new Uint8ClampedArray(b);
  str2array(value)
    .reverse()
    .map((val, index) => (a[index] = parseInt(val, 16)));

  return new Int32Array(b)[0];
});
//常用32位2进制表示的整数，最高位为1表示2的31次方
Vue.filter("uint32", function (value) {
  if (!value) return "----";

  var b = new ArrayBuffer(4); //4*8 32位
  var a = new Uint8ClampedArray(b);
  str2array(value)
    .reverse()
    .map((val, index) => (a[index] = parseInt(val, 16)));

  return new Uint32Array(b)[0];
});

//常用32位2进制表示的小数，最高位为1表示2的31次方
// _________________________________________________________
// 31        30              22                            0
// |符号位占1|   指数位占8      |         尾数部分占23       |
// _________________________________________________________

// 17.625在内存中的存储

// 首先要把17.625换算成二进制：10001.101  即 2^5 2^0 . 2^-1 2^-3

// 将10001.101右移，直到小数点前只剩1位：1.0001101 * 2^4 因为右移动了四位。

// 底数：因为小数点前必为1，所以IEEE规定只记录小数点后的就好。所以，此处的底数为：0001101
// 指数：实际为4，必须加上127(转出的时候，减去127)，所以为131。也就是10000011
// 指数占8位，表示0-255之间的数值，为方便判断指数正负，我们就要用一个中间值127来辅助
// 比如，8位的指数在内存中存储的值是125，然后读取的时候125-127得到-2，这个-2就是真实的指数值
// 通过这种方式就可以方便存储数值为-127 ~ 128的指数

// 符号部分是正数，所以是0
// 综上所述，17.625在内存中的存储格式是：符号, 10即E的多少次方, 小数1.后面部分
// +   131(4+127)  1. 0001101
// 0    10000011      0001101 00000000 00000000

Vue.filter("float32", function (value) {
  if (!value) return "----";

  var b = new ArrayBuffer(4); //4*8 32位
  var a = new Uint8ClampedArray(b);
  str2array(value)
    .reverse()
    .map((val, index) => (a[index] = parseInt(val, 16)));

  return new Float32Array(b)[0];
});
//常用64位2进制表示的小数，最高位为1表示2的31次方
// _________________________________________________________
// 63        62              51                            0
// |符号位占1|   指数位占11      |         尾数部分占52       |
// _________________________________________________________

// 17.625双精度在内存中的存储格式类似，区别是指数基数为1023的移码
// +   1027(4+1023)  1. 0001101
// PLC编程尽量使用整数，不推荐使用浮点数
Vue.filter("float64", function (value) {
  if (!value) return "----";

  var b = new ArrayBuffer(8); //8*8 64位
  var a = new Uint8ClampedArray(b);
  str2array(value)
    .reverse()
    .map((val, index) => (a[index] = parseInt(val, 16)));

  return new Float64Array(b)[0];
});
